package tgeo;

import java.nio.charset.Charset;
import java.util.Map;

import org.apache.commons.codec.binary.Base64;
import org.apache.commons.codec.binary.Hex;
import org.eclipse.swt.SWT;
import org.eclipse.swt.custom.StyledText;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.events.SelectionListener;
import org.eclipse.swt.graphics.Font;
import org.eclipse.swt.layout.FormAttachment;
import org.eclipse.swt.layout.FormData;
import org.eclipse.swt.layout.FormLayout;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Combo;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Layout;
import org.eclipse.ui.part.ViewPart;

public class Base64View extends ViewPart {

	Button btnBase64enc = null;
	Button btnBase64dec = null;

	Button radioHex = null;
	Button radioStr = null;
	Combo cboEncoding = null;
	Button chkBlockSelection = null;
	StyledText txtArea = null;
	Button chkWrap = null;


	final int PAD = 10;

	public Base64View() {
	}

	@Override
	public void createPartControl(final Composite parent) {
		Layout layout = new FormLayout();
		parent.setLayout(layout);
		Composite composite0 = new Composite(parent, SWT.NONE);
		composite0.setLayout(parent.getLayout());

		FormData data = null;
		btnBase64enc = new Button(parent, SWT.PUSH);
		btnBase64dec = new Button(parent, SWT.PUSH);
		radioHex = new Button(composite0, SWT.RADIO);
		radioStr = new Button(composite0, SWT.RADIO);
		cboEncoding = new Combo(composite0, SWT.BORDER);
		chkBlockSelection = new Button(parent, SWT.CHECK);
		chkWrap = new Button(parent, SWT.CHECK);
		txtArea = new StyledText(parent, SWT.BORDER | SWT.V_SCROLL
				| SWT.H_SCROLL);

		data = new FormData();
		data.top = new FormAttachment(0, PAD);
		data.left = new FormAttachment(0, PAD);
		btnBase64enc.setLayoutData(data);

		data = new FormData();
		data.top = new FormAttachment(0, PAD);
		data.left = new FormAttachment(btnBase64enc, PAD);
		btnBase64dec.setLayoutData(data);

		data = new FormData();
		data.top = new FormAttachment(btnBase64dec, PAD);
		data.left = new FormAttachment(0, PAD);
		composite0.setLayoutData(data);

		data = new FormData();
		data.top = new FormAttachment(0, PAD);
		data.left = new FormAttachment(0, PAD);
		radioHex.setLayoutData(data);

		data = new FormData();
		data.top = new FormAttachment(radioHex, PAD);
		data.left = new FormAttachment(0, PAD);
		radioStr.setLayoutData(data);

		data = new FormData();
		data.top = new FormAttachment(radioHex, PAD);
		data.left = new FormAttachment(radioStr, PAD);
		cboEncoding.setLayoutData(data);

		data = new FormData();
		data.top = new FormAttachment(composite0, PAD);
		data.left = new FormAttachment(0, PAD);
		chkBlockSelection.setLayoutData(data);

		data = new FormData();
		data.top = new FormAttachment(composite0, PAD);
		data.left = new FormAttachment(chkBlockSelection, PAD);
		chkWrap.setLayoutData(data);
		
		data = new FormData();
		data.top = new FormAttachment(chkBlockSelection, PAD);
		data.left = new FormAttachment(0, PAD);
		data.right = new FormAttachment(100, -PAD);
		data.bottom = new FormAttachment(100, -PAD);
		txtArea.setLayoutData(data);

		btnBase64enc.setText("Base64 encoding");
		btnBase64dec.setText("Base64 decoding");
		radioHex.setText("Hex");
		radioStr.setText("Text");
		radioStr.setSelection(true);
		chkBlockSelection.setText("Block Selection");
		chkWrap.setText("Wrap");
		txtArea.setFont(new Font(null, "fixedsys", 10, SWT.NONE));

		Map<String, Charset> mapCharset = Charset.availableCharsets();
		for (String k : mapCharset.keySet()) {
			Charset charset = mapCharset.get(k);
			cboEncoding.add(charset.toString());
		}
		cboEncoding.setText(Charset.defaultCharset().toString());

		btnBase64enc.addSelectionListener(new SelectionListener() {
			@Override
			public void widgetSelected(SelectionEvent e) {
				try {
					String msg = txtArea.getText();
					if (radioHex.getSelection()) {
						msg = msg.replaceAll("[^a-zA-Z0-9]", "");
						byte[] byteDec = new byte[msg.length() / 2];
						for (int i = 0; i < msg.length() / 2; i++) {
							byteDec[i] = (byte) (int) Integer.valueOf(msg
									.substring(i * 2, (i + 1) * 2), 16);
						}
						Base64 base64 = new Base64();
						txtArea.setText(base64.encodeToString(byteDec));
					} else {
						Base64 base64 = new Base64();
						byte[] byteDec = msg.getBytes(cboEncoding.getText());
						txtArea.setText(base64.encodeToString(byteDec));
					}
				} catch (Exception e1) {
					e1.printStackTrace();
				}
			}

			@Override
			public void widgetDefaultSelected(SelectionEvent e) {
			}
		});

		btnBase64dec.addSelectionListener(new SelectionListener() {
			@Override
			public void widgetSelected(SelectionEvent e) {
				String msg = txtArea.getText();
				try {
					if (radioHex.getSelection()) {
						Base64 base64 = new Base64();
						byte[] byteDec = base64.decode(msg);
//						StringBuffer sb = new StringBuffer();
//						for(int i=0; i<byteDec.length; i++){
//							sb.append(String.format("%02x", byteDec[i]));
//							if((i+1)%16 == 0){
//								sb.append("\n");
//							}
//						}
//						txtArea.setText(sb.toString());
						txtArea.setText(Hex.encodeHexString(byteDec));
					} else {
						Base64 base64 = new Base64();
						byte[] byteDec = base64.decode(msg);
						txtArea.setText(new String(byteDec, cboEncoding
								.getText()));
					}
				} catch (Exception e1) {
					e1.printStackTrace();
				}
			}

			@Override
			public void widgetDefaultSelected(SelectionEvent e) {
			}
		});

		chkBlockSelection.addSelectionListener(new SelectionListener() {
			@Override
			public void widgetSelected(SelectionEvent e) {
				txtArea.setBlockSelection(chkBlockSelection.getSelection());
			}

			@Override
			public void widgetDefaultSelected(SelectionEvent e) {
			}
		});
		chkWrap.addSelectionListener(new SelectionListener() {
			@Override
			public void widgetSelected(SelectionEvent e) {
				txtArea.setWordWrap(chkWrap.getSelection());
			}

			@Override
			public void widgetDefaultSelected(SelectionEvent e) {
			}
		});
	}

	@Override
	public void setFocus() {
	}

}
